'use client';

import type { TBody, TMetadata } from '@/types';
import { type ChangeEvent, useRef, useState } from 'react';
import { useMutation } from '@tanstack/react-query';
import type { IUploadAvatarFileBody } from '@/interfaces';
import { uploadAvatarFile } from '@/services/api';
import Script from 'next/script';
import useUser from '@/hooks/useUser';
import useToast, { LoginReminderContent } from '@/hooks/useToast';
import ErrorPage from '@/app/[locale]/error/error';
import LoadPage from '@/app/[locale]/load/load';
import FooterH5IcpPage from '@/app/[locale]/mobile/footerH5Icp';
import FooterH5Page from '@/app/[locale]/mobile/footerH5';

export default function AvatarH5Page({ metadata }: { metadata: TMetadata }) {
  return (
    <>
      <Avatar metadata={metadata} />
      <FooterH5IcpPage metadata={metadata} />
      <FooterH5Page metadata={metadata} />
    </>
  );
}

const Avatar = ({ metadata }: { metadata: TMetadata }) => {
  const userQuery = useUser(metadata);
  const cropperImageRef = useRef(null);
  const cropperSelectionRef = useRef(null);
  const [isEdit, setIsEdit] = useState(
    !!(
      userQuery.data &&
      userQuery.data.user &&
      userQuery.data.user.details.largeAvatarUrl
    ),
  );
  const [form, setForm] = useState({
    avatar: '',
    file: '',
    fileObjectUrl: '',
  });

  const { show } = useToast();

  const uploadAvatarFileMutation = useMutation(
    async (variables: TBody<IUploadAvatarFileBody>) => {
      await uploadAvatarFile(variables);
    },
  );

  function clearUploadData() {
    if (form.fileObjectUrl) {
      URL.revokeObjectURL(form.fileObjectUrl);
    }
    setForm({
      avatar: '',
      file: '',
      fileObjectUrl: '',
    });
  }

  async function handleCallback(file: Blob) {
    if (!file) {
      show({
        type: 'DANGER',
        message: '文件不存在',
      });
      return;
    }

    try {
      await uploadAvatarFileMutation.mutateAsync({
        data: {
          file,
        },
      });

      setIsEdit(true);
      clearUploadData();

      show({
        type: 'SUCCESS',
        message: isEdit ? '更新头像完成' : '上传头像完成',
      });

      setTimeout(() => {
        show({
          type: 'INFO',
          message: '即将返回主页',
        });
      }, 1000);

      setTimeout(() => {
        location.href = `/users/${
          userQuery.data && userQuery.data.user && userQuery.data.user.id
        }`;
      }, 1500);
    } catch (e) {
      uploadAvatarFileMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  async function onClickUpload() {
    if (isEdit) {
      if (!confirm('当前已存在头像，确定要更新吗？')) {
        return;
      }
    }

    if (!(userQuery.data && userQuery.data.user)) {
      show({
        title: '还未登录，是否进行登录?',
        content: <LoginReminderContent />,
      });
      return;
    }

    const current = cropperSelectionRef.current;
    if (!current || !cropperImageRef.current) {
      show({
        type: 'DANGER',
        message: '裁剪元素不存在',
      });
      return;
    }

    const { file } = form;
    if (!file) {
      show({
        type: 'DANGER',
        message: '文件不存在，请上传文件',
      });
      return;
    }

    try {
      // @ts-ignore
      const canvas = await current.$toCanvas({
        // @ts-ignore
        beforeDraw: (context, canvas) => {
          const { width, height } = canvas;

          if (width !== 260 || height !== 260) {
            const message = '裁剪宽高无效，请点击重置按钮';
            show({
              type: 'DANGER',
              message,
            });
            return Promise.reject(message);
          }
          return Promise.resolve();
        },
      });

      // @ts-ignore
      canvas.toBlob(handleCallback, file.type, 1);
    } catch (e: any) {
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onClickTop() {
    if (cropperImageRef.current) {
      // @ts-ignore
      cropperImageRef.current.$translate(0, -6);
    }
  }

  function onClickBottom() {
    if (cropperImageRef.current) {
      // @ts-ignore
      cropperImageRef.current.$translate(0, 6);
    }
  }

  function onClickLeft() {
    if (cropperImageRef.current) {
      // @ts-ignore
      cropperImageRef.current.$translate(-6, 0);
    }
  }

  function onClickRight() {
    if (cropperImageRef.current) {
      // @ts-ignore
      cropperImageRef.current.$translate(6, 0);
    }
  }

  function onClickPlus() {
    if (cropperImageRef.current) {
      // @ts-ignore
      cropperImageRef.current.$zoom(0.1);
    }
  }

  function onClickDash() {
    if (cropperImageRef.current) {
      // @ts-ignore
      cropperImageRef.current.$zoom(-0.1);
    }
  }

  function onClickReset() {
    if (cropperImageRef.current && cropperSelectionRef.current) {
      // @ts-ignore
      cropperImageRef.current.$resetTransform();
      // @ts-ignore
      cropperImageRef.current.$center('cover');
      // @ts-ignore
      cropperSelectionRef.current.$change(0, 0, 260, 260);
      // @ts-ignore
      cropperSelectionRef.current.$center();
    }
  }

  function onChangeForm(
    e: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'avatar') {
      if (form.fileObjectUrl) {
        URL.revokeObjectURL(form.fileObjectUrl);
      }

      const file = (e.target as any).files[0];
      const fileObjectUrl = URL.createObjectURL(file);
      setForm({
        ...form,
        [name]: value,
        file,
        fileObjectUrl,
      });
    }
  }

  function onLoadCropper() {
    if (cropperImageRef.current && cropperSelectionRef.current) {
      // @ts-ignore
      cropperImageRef.current.$ready(() => {
        // @ts-ignore
        cropperSelectionRef.current.$center();
      });
    }
  }

  if (userQuery.data) {
    // @ts-ignore
    // @ts-ignore
    return (
      <>
        <div className="col p-2">
          <div className="card rounded-5 border-0">
            <div className="card-body">
              <div className="bg-white container-fluid">
                <div className="lead text-center mt-4">
                  {isEdit ? '编辑头像' : '上传头像'}
                </div>
                <div className="row my-5 mx-0">
                  <div className="col d-flex align-items-center justify-content-center flex-column">
                    {/*// @ts-ignore*/}
                    <cropper-canvas
                      style={{ width: 330, height: 330 }}
                      id="cropper-canvas"
                      background
                    >
                      {/*// @ts-ignore*/}
                      <cropper-image
                        ref={cropperImageRef}
                        rotatable="false"
                        skewable="false"
                        id="cropper-image"
                        src={form.fileObjectUrl || '/images/avatar.png'}
                        alt="avatar"
                      >
                        {/*// @ts-ignore*/}
                      </cropper-image>
                      {/*// @ts-ignore*/}
                      <cropper-shade></cropper-shade>
                      {/*// @ts-ignore*/}
                      <cropper-handle action="select" plain></cropper-handle>
                      {/*// @ts-ignore*/}
                      <cropper-selection
                        ref={cropperSelectionRef}
                        width="260"
                        height="260"
                        id="cropper-selection"
                        movable
                        resizable
                        outlined
                      >
                        {/*// @ts-ignore*/}
                        <cropper-grid role="grid" hidden></cropper-grid>
                        {/*// @ts-ignore*/}
                        <cropper-crosshair centered></cropper-crosshair>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          className="rounded-circle"
                          action="move"
                          theme-color="rgba(255, 255, 255, 0.35)"
                        >
                          {/*// @ts-ignore*/}
                        </cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="n-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="e-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="s-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="w-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="ne-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="nw-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="se-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                        <cropper-handle
                          action="sw-resize"
                          hidden
                          // @ts-ignore
                        ></cropper-handle>
                        {/*// @ts-ignore*/}
                      </cropper-selection>
                      {/*// @ts-ignore*/}
                    </cropper-canvas>
                    <div className="hstack gap-2 flex-wrap justify-content-center my-5">
                      <button
                        onClick={onClickTop}
                        type="button"
                        className="btn btn-light"
                      >
                        上移
                      </button>
                      <button
                        onClick={onClickBottom}
                        type="button"
                        className="btn btn-light"
                      >
                        下移
                      </button>
                      <button
                        onClick={onClickLeft}
                        type="button"
                        className="btn btn-light"
                      >
                        左移
                      </button>
                      <button
                        onClick={onClickRight}
                        type="button"
                        className="btn btn-light"
                      >
                        右移
                      </button>
                      <button
                        onClick={onClickPlus}
                        type="button"
                        className="btn btn-light"
                      >
                        放大
                      </button>
                      <button
                        onClick={onClickDash}
                        type="button"
                        className="btn btn-light"
                      >
                        缩小
                      </button>
                      <button
                        onClick={onClickReset}
                        type="button"
                        className="btn btn-light"
                      >
                        重置
                      </button>
                    </div>
                  </div>
                  <div className="col d-flex align-items-center justify-content-center flex-column">
                    <div className="row">
                      <div className="col">
                        <div className="input-group">
                          <input
                            disabled={uploadAvatarFileMutation.isLoading}
                            type="file"
                            accept="image/*"
                            className="form-control"
                            id="avatar"
                            name="avatar"
                            value={form.avatar}
                            onChange={onChangeForm}
                            aria-describedby="inputGroupFileAddon04"
                            aria-label="Upload"
                          />
                          <button
                            onClick={onClickUpload}
                            disabled={uploadAvatarFileMutation.isLoading}
                            className="btn btn-outline-secondary"
                            type="button"
                            id="inputGroupFileAddon04"
                          >
                            {uploadAvatarFileMutation.isLoading && (
                              <span
                                className="spinner-border spinner-border-sm me-2"
                                role="status"
                                aria-hidden="true"
                              ></span>
                            )}
                            {isEdit ? '更新头像' : '上传头像'}
                          </button>
                        </div>
                        <ol className="form-text">
                          <li>请选择一张宽高大于 260px 头像图片裁剪</li>
                          <li>鼠标滚轮或者点击缩放按钮可以对图片进行缩放</li>
                        </ol>
                      </div>
                    </div>
                    <div className="row my-5">
                      <div className="col d-flex justify-content-center align-items-center">
                        {/*// @ts-ignore*/}
                        <cropper-viewer
                          className="rounded-circle"
                          selection="#cropper-selection"
                          style={{ width: 260 }}
                        >
                          {/*// @ts-ignore*/}
                        </cropper-viewer>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <Script src="/lib/cropper.min.js" onLoad={onLoadCropper} />
      </>
    );
  }

  if (userQuery.error) {
    return <ErrorPage error={userQuery.error} />;
  }

  return <LoadPage />;
};
